package com.hui.qiniucloud.controller;

import com.hui.qiniucloud.service.ITtsV3Service;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.io.ByteArrayOutputStream;
import java.time.Duration;
import java.util.List;
import java.util.ArrayList;

@Slf4j
@RestController
@RequestMapping("/api/tts")
@CrossOrigin(origins = "*")
@Tag(name = "TTS V3 API", description = "V3双向流式文字转语音接口")
public class TtsV3Controller {

    @Autowired
    private ITtsV3Service ttsV3Service;

    @PostMapping("/synthesize")
    @Operation(summary = "文字转语音", description = "使用V3双向流式API进行文字转语音，返回音频数据")
    public ResponseEntity<Flux<byte[]>> synthesize(
            @RequestBody ITtsV3Service.TtsRequest request) {
        
        log.info("收到TTS合成请求，文本: '{}'", request.getText());
        
        if (request.getText() == null || request.getText().trim().isEmpty()) {
            return ResponseEntity.badRequest().build();
        }

        // 设置默认值
        if (request.getFormat() == null) request.setFormat("mp3");
        if (request.getSampleRate() == null) request.setSampleRate(24000);
        if (request.getBitRate() == null) request.setBitRate(64000);
        if (request.getSpeed() == null) request.setSpeed(0);
        if (request.getLoudnessRate() == null) request.setLoudnessRate(0);

        Flux<byte[]> audioStream = ttsV3Service.synthesizeSpeech(request)
                .filter(response -> response.getAudioData() != null && response.getAudioData().length > 0)
                .map(ITtsV3Service.TtsResponse::getAudioData)
                .timeout(Duration.ofSeconds(30))
                .onErrorResume(throwable -> {
                    log.error("TTS合成过程出错: {}", throwable.getMessage());
                    return Flux.empty();
                });

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.set("Content-Disposition", "attachment; filename=\"speech.mp3\"");

        return ResponseEntity.ok()
                .headers(headers)
                .body(audioStream);
    }

    @PostMapping(value = "/synthesize/stream", produces = "text/event-stream")
    @CrossOrigin(origins = "*", allowedHeaders = "*")
    @Operation(summary = "流式文字转语音", description = "使用V3双向流式API进行文字转语音，返回Server-Sent Events流")
    public Flux<ServerSentEvent<String>> synthesizeStream(
            @RequestBody ITtsV3Service.TtsRequest request) {
        
        log.info("收到流式TTS合成请求，文本: '{}'", request.getText());
        
        if (request.getText() == null || request.getText().trim().isEmpty()) {
            return Flux.just(ServerSentEvent.<String>builder()
                    .event("error")
                    .data("文本不能为空")
                    .build());
        }

        // 设置默认值
        if (request.getFormat() == null) request.setFormat("mp3");
        if (request.getSampleRate() == null) request.setSampleRate(24000);
        if (request.getBitRate() == null) request.setBitRate(64000);
        if (request.getSpeed() == null) request.setSpeed(0);
        if (request.getLoudnessRate() == null) request.setLoudnessRate(0);

        return ttsV3Service.synthesizeSpeech(request)
                .map(response -> {
                    if (response.isFinished()) {
                        return ServerSentEvent.<String>builder()
                                .event("finished")
                                .data("合成完成")
                                .build();
                    } else if (response.getAudioData() != null && response.getAudioData().length > 0) {
                        // 将音频数据转换为Base64
                        String audioBase64 = java.util.Base64.getEncoder().encodeToString(response.getAudioData());
                        return ServerSentEvent.<String>builder()
                                .event("audio")
                                .data(audioBase64)
                                .build();
                    } else {
                        return ServerSentEvent.<String>builder()
                                .event("info")
                                .data("句子: " + (response.getText() != null ? response.getText() : ""))
                                .build();
                    }
                })
                .timeout(Duration.ofSeconds(30))
                .onErrorResume(throwable -> {
                    log.error("流式TTS合成过程出错: {}", throwable.getMessage());
                    return Flux.just(ServerSentEvent.<String>builder()
                            .event("error")
                            .data("合成失败: " + throwable.getMessage())
                            .build());
                });
    }

    @PostMapping("/synthesize/mix")
    @Operation(summary = "混音文字转语音", description = "使用混音功能进行文字转语音")
    public ResponseEntity<Flux<byte[]>> synthesizeMix(
            @RequestBody MixTtsRequest request) {
        
        log.info("收到混音TTS合成请求，文本: '{}', 混音音色数: {}", 
                request.getText(), request.getMixSpeakers().size());
        
        if (request.getText() == null || request.getText().trim().isEmpty()) {
            return ResponseEntity.badRequest().build();
        }

        if (request.getMixSpeakers() == null || request.getMixSpeakers().isEmpty()) {
            return ResponseEntity.badRequest().build();
        }

        // 验证混音因子总和为1
        double totalFactor = request.getMixSpeakers().stream()
                .mapToDouble(MixSpeakerItem::getMixFactor)
                .sum();
        
        if (Math.abs(totalFactor - 1.0) > 0.01) {
            log.error("混音因子总和必须为1.0，当前为: {}", totalFactor);
            return ResponseEntity.badRequest().build();
        }

        // 构建TtsRequest
        ITtsV3Service.TtsRequest ttsRequest = new ITtsV3Service.TtsRequest();
        ttsRequest.setText(request.getText());
        ttsRequest.setSpeaker("custom_mix_bigtts");
        ttsRequest.setFormat(request.getFormat() != null ? request.getFormat() : "mp3");
        ttsRequest.setSampleRate(request.getSampleRate() != null ? request.getSampleRate() : 24000);
        ttsRequest.setBitRate(request.getBitRate() != null ? request.getBitRate() : 64000);
        ttsRequest.setSpeed(request.getSpeed() != null ? request.getSpeed() : 0);
        ttsRequest.setLoudnessRate(request.getLoudnessRate() != null ? request.getLoudnessRate() : 0);

        // 构建混音配置
        ITtsV3Service.MixSpeaker mixSpeaker = new ITtsV3Service.MixSpeaker();
        List<ITtsV3Service.SpeakerMix> speakers = new ArrayList<>();
        
        for (MixSpeakerItem item : request.getMixSpeakers()) {
            ITtsV3Service.SpeakerMix speakerMix = new ITtsV3Service.SpeakerMix();
            speakerMix.setSourceSpeaker(item.getSourceSpeaker());
            speakerMix.setMixFactor(item.getMixFactor());
            speakers.add(speakerMix);
        }
        
        mixSpeaker.setSpeakers(speakers);
        ttsRequest.setMixSpeaker(mixSpeaker);

        Flux<byte[]> audioStream = ttsV3Service.synthesizeSpeech(ttsRequest)
                .filter(response -> response.getAudioData() != null && response.getAudioData().length > 0)
                .map(ITtsV3Service.TtsResponse::getAudioData)
                .timeout(Duration.ofSeconds(30))
                .onErrorResume(throwable -> {
                    log.error("混音TTS合成过程出错: {}", throwable.getMessage());
                    return Flux.empty();
                });

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.set("Content-Disposition", "attachment; filename=\"mixed_speech.mp3\"");

        return ResponseEntity.ok()
                .headers(headers)
                .body(audioStream);
    }

    @GetMapping("/speakers")
    @Operation(summary = "获取可用音色列表", description = "获取支持的音色列表")
    public ResponseEntity<List<String>> getSpeakers() {
        List<String> speakers = List.of(
                "zh_female_shuangkuaisisi_moon_bigtts",
                "zh_male_ahu_conversation_wvae_bigtts", 
                "zh_female_yunzhu_dialogue_bigtts",
                "zh_male_qinlang_dialogue_bigtts",
                "zh_female_ximenglong_dialogue_bigtts",
                "zh_male_bvlazysheep"
        );
        return ResponseEntity.ok(speakers);
    }

    @GetMapping("/formats")
    @Operation(summary = "获取支持的音频格式", description = "获取支持的音频输出格式")
    public ResponseEntity<List<String>> getFormats() {
        List<String> formats = List.of("mp3", "ogg_opus", "pcm");
        return ResponseEntity.ok(formats);
    }

    /**
     * 混音TTS请求类
     */
    public static class MixTtsRequest {
        private String text;
        private List<MixSpeakerItem> mixSpeakers;
        private String format = "mp3";
        private Integer sampleRate = 24000;
        private Integer bitRate = 64000;
        private Integer speed = 0;
        private Integer loudnessRate = 0;
        
        // getters and setters
        public String getText() { return text; }
        public void setText(String text) { this.text = text; }
        public List<MixSpeakerItem> getMixSpeakers() { return mixSpeakers; }
        public void setMixSpeakers(List<MixSpeakerItem> mixSpeakers) { this.mixSpeakers = mixSpeakers; }
        public String getFormat() { return format; }
        public void setFormat(String format) { this.format = format; }
        public Integer getSampleRate() { return sampleRate; }
        public void setSampleRate(Integer sampleRate) { this.sampleRate = sampleRate; }
        public Integer getBitRate() { return bitRate; }
        public void setBitRate(Integer bitRate) { this.bitRate = bitRate; }
        public Integer getSpeed() { return speed; }
        public void setSpeed(Integer speed) { this.speed = speed; }
        public Integer getLoudnessRate() { return loudnessRate; }
        public void setLoudnessRate(Integer loudnessRate) { this.loudnessRate = loudnessRate; }
    }

    /**
     * 混音音色配置项
     */
    public static class MixSpeakerItem {
        private String sourceSpeaker;
        private Double mixFactor;
        
        public String getSourceSpeaker() { return sourceSpeaker; }
        public void setSourceSpeaker(String sourceSpeaker) { this.sourceSpeaker = sourceSpeaker; }
        public Double getMixFactor() { return mixFactor; }
        public void setMixFactor(Double mixFactor) { this.mixFactor = mixFactor; }
    }
}